package com.rpc.client.framework;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.InetSocketAddress;
import java.net.Socket;


/**
 * com.rpc.client.framework
 *
 * @author humdeef
 * @since 2019-07-17
 */
public class RpcClient {

  public static <T> T getRemoteProxy(final Class<T> interfaceClazz,
      final InetSocketAddress inetSocketAddress) {
    return (T) Proxy.newProxyInstance(interfaceClazz.getClassLoader(),
        new Class<?>[]{interfaceClazz}, new InvocationHandler() {
          @Override
          public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            try (Socket socket = new Socket()) {
              socket.connect(inetSocketAddress);
              // 报文格式
              // 第一个参数为暴露的接口名(string)
              // 第二个参数 方法名字（string）
              // 第三个参数 参数类型列表(Class<?>[]
              // 第四个参数 参数值列表（Object[]）)
              try (ObjectOutputStream serilizer = new ObjectOutputStream(socket.getOutputStream());
                  ObjectInputStream deserilizer = new ObjectInputStream(socket.getInputStream())) {
                // 网络传输序列化结果
                serilizer.writeUTF(interfaceClazz.getName());
                serilizer.writeUTF(method.getName());
                serilizer.writeObject(method.getParameterTypes());
                serilizer.writeObject(args);
                // 反序列化结果
                return deserilizer.readObject();

              } catch (Exception e) {
                e.printStackTrace();
              }
            } catch (Exception e) {
              e.printStackTrace();
            }
            return null;
          }
        });
  }
}
